#include "ROMS_Menu.h"

//added includes
#include "std_lib_facilities.h"
using namespace std;
using namespace ROMS;

ROMS_Menu::ROMS_Menu()
{
}

void ROMS_Menu::display_main_menu() const 
{
	//A.3
	cout << "\nMAIN MENU \n";
	cout << "1-Info 2-Read 3-Show 4-Find 5-Update 6-Exit\n";
}
void ROMS_Menu::display_info() const
{
	//A.3
	cout << "\nWard-team Project Part I: Restaurant Order Management System\n";
}

void ROMS_Menu::read_recipes_ingredients(string fname)
{
	recipe_location = fname; //added by HHC
	//A.1, 2 & 3 merge
	ifstream ist;

	//A.1 read ingredients	//should error check
	int num_rec = get_file_info(ist, "Please enter recipe data file name: ", fname);
	ingredients.clear();	//start with an empty list
	read_file(ist, num_rec, ROMS_Menu::Ingred);
	cout << "read " << ingredients.size() << " ingredient items \n";
	//A.1 read and store the recipe data	//should error check
	ist >> num_rec;
	recipes.clear();	//start with an empty list
	read_file(ist, num_rec, ROMS_Menu::Rec);
	cout << "read " << recipes.size() << " recipes \n";
	ist.close();
}

void ROMS_Menu::Read_orders(string fname)
{
	
	order_location = fname; //added by HHC
	cout<< "Order location "<<order_location;
	//A.2 read and store the order and order item data 
	ifstream ist;
	int num_orders = get_file_info(ist, "Please enter orders data file name: ", fname);
	orders.clear();	//start with an empty list
	read_file(ist, num_orders, ROMS_Menu::Ord);
	cout << "read " << orders.size() << " orders \n";

	//A.2 read order item data	
	int num_items = 0;
	order_items.clear();	//start with an empty list
	ist >> num_items;
	read_file(ist, num_items, ROMS_Menu::Ord_item);
	cout << "read " << order_items.size() << " order items \n";
	ist.close();
}

void ROMS_Menu::read_catprds(string fname)
{
	
	catmenu_location = fname; //added by HHC

	ifstream ist;
	int num_items;
	//A.3 read the category and menu data
	int num_cats = get_file_info(ist, "Please enter file name for category/menu data: ", fname);
	categories.clear();	//start with an empty list
	read_file(ist, num_cats, ROMS_Menu::Cats);
	cout << "read " << categories.size() << " categories \n";

	//A.3 read menu items	//should error check
	ist >> num_items;	//get number of menu items
	menu_items.clear();	//start with an empty list
	read_file(ist, num_items, Menu_entry);
	cout << "read " << menu_items.size() << " menu items \n";
	ist.close();
	return;
}

/* Save the data, and exit.. TTL Part II B.1 */
void ROMS_Menu::save()
{
	/*if(categories.size()==0 || menu_items.size()==0 || ingredients.size()==0 || recipes.size()==0 || orders.size()==0 || order_items.size()==0)
	{
		cout << "\nCertain files have not been read. Read files to initialize data.\n";
		return;
	}*/
	
	if(catmenu_location=="")//edited by HHC
	{
		cout << "\nCategories and Menu Items have not been read. Read files to initialize data.\n";
	}
	else
	{
		ofstream out1(catmenu_location.c_str(),ios_base::trunc);//edited by HHC
		
		out1 << categories.size() << "\n";
		for(int i = 0; i < categories.size();i++)
		{
			out1 << categories[i].Category::get_cat_id() << "\t";
			out1 << categories[i].Category::get_cat_name();
			out1 << "\n";
		}
		
		out1 << "\n";
		out1 << menu_items.size() << "\n";
		for(int i = 0; i < menu_items.size();i++)
		{
			out1 << menu_items[i].Menu_Item::get_menu_item_id() << "\t";
			out1 << menu_items[i].Menu_Item::get_cat_id() << "\t";
			out1 << menu_items[i].Menu_Item::get_recipe_id() << "\t";
			out1 << menu_items[i].Menu_Item::get_name() << "\t";
			out1 << menu_items[i].Menu_Item::get_price() << "\t";
			out1 << menu_items[i].Menu_Item::get_description() << "#";
			out1 << "\n";
		}
		
		out1.close();
	}

	if(recipe_location=="")//edited by HHC
	{
		cout << "\nRecipes have not been read. Read files to initialize data.\n";
	}
	else
	{
		ofstream out2(recipe_location.c_str(),ios_base::trunc);//edited by HHC
		
		out2 << ingredients.size() << "\n";
		for(int i = 0; i < ingredients.size();i++)
		{
			out2 << ingredients[i].Ingredient::get_ingredient_id() << "\t";
			out2 << ingredients[i].Ingredient::get_recipe_id() << "\t";
			out2 << ingredients[i].Ingredient::get_amt() << "\t";
			out2 << ingredients[i].Ingredient::get_units() << "\t";
			out2 << ingredients[i].Ingredient::get_name();
			out2 << "\n";
		}
		
		out2 << "\n";
		out2 << recipes.size() << "\n";
		for(int i = 0; i < recipes.size();i++)
		{
			out2 << recipes[i].Recipe::get_rec_id() << "\t";
			out2 << recipes[i].Recipe::get_chef() << "\t";
			out2 << recipes[i].Recipe::getInstructionsString() << "#";
			out2 << "\n";
		}
		
		out2.close();
	}

	if(order_location=="")//edited by HHC
	{
		cout << "\nCategories and Menu Items have not been read. Read files to initialize data.\n";
	}
	else
	{
		ofstream out3(order_location.c_str(),ios_base::trunc);//edited by HHC
		
		out3 << orders.size() << "\n"; //THIS NEEDS WORK *****
		for(int i = 0; i < orders.size();i++)
		{
			out3 << orders[i].Order::get_order_id() << "\t";
			out3 << orders[i].Order::getServerId() << "\t";
			out3 << orders[i].Order::get_table_id() << "\t";
			out3 << orders[i].Order::getYear() << "\t";
			out3 << orders[i].Order::getMonth() << "\t";
			out3 << orders[i].Order::getDay() << "\t";
			out3 << orders[i].Order::getHour() << "\t";
			out3 << orders[i].Order::getMinute();
			out3 << "\n";
		}
		
		out3 << "\n";
		out3 << order_items.size() << "\n";
		for(int i = 0; i < order_items.size();i++)
		{
			out3 << order_items[i].Order_Item::get_seat_id() << "\t";
			out3 << order_items[i].Order_Item::get_order_id() << "\t";
			out3 << order_items[i].Order_Item::get_menu_item_id() << "\t";
			out3 << order_items[i].Order_Item::get_qty();
			out3 << "\n";
		}
		
		out3.close();
	}
}
/* end of save and exit data */

void ROMS_Menu::show() const 
{	//Below is some old code from Part I. What changes, if any are needed for Part II?
	//B.1, a, b, c merge	//cout << "Show queries \n";
	cout << "Enter Show query number:" << endl << "1-Menu Item Recipe 2-All Menu Items by Chef 3-All Menu Items in a Category\n";
	int query_num;
	cin >> query_num;
	switch (query_num) 
	{
	case 1:
		{
			//B.1.a show a Menu Item Recipe
			string item_name;
			int i;
			cout <<"Enter Menu Item Name\n";
			cin >> item_name;
			for (i = 0; i < (int) menu_items.size(); ++i)
				if (menu_items[i].get_name() == item_name) break;
			if (i == (int) menu_items.size()) {
				cout << "Menu Name Not Found\n";
				break;
			}
			else {//found Menu Item, now find recipe and print it
				cout << menu_items[i].get_description() << endl;
				int rec_id = menu_items[i].get_recipe_id();
				int j;
				for (j = 0; j < (int) recipes.size(); ++j)
					if(rec_id == recipes[j].get_rec_id()) break;
				if (j == (int) recipes.size()) {
					cout << "Recipe ID not found -- data bug\n";
					break;
				}
				//print recipe j
				cout << recipes[j].display() << endl;
				//retrieve and print recipe j ingredients
				for (int k = 0; k < (int) ingredients.size(); ++k)
					if(rec_id == ingredients[k].get_rec_id()) cout << ingredients[k].display() << endl;
				cout << endl;
			}
		}
	case 2: 
		{
			//B.1.b list All Menu Items by Chef
			cout << menu_items.size() << " menu items sorted by chef\n";
			vector<Recipe> temp_recipes = recipes;
			//sort the recipes by chef, then print the menu items in the order of their recipe
			//sort(temp_recipes.begin(), temp_recipes.end(), SortRecipesByChef());
			for (int i = 0; i< (int) temp_recipes.size(); ++i) {
				cout << "Chef: " << temp_recipes[i].get_chef() << endl;
				//loop thru sorted recipes and print requested coresponding Menu_Item info
				for (int j = 0; j< (int) menu_items.size(); ++j)
					if (menu_items[j].get_recipe_id() == temp_recipes[i].get_rec_id())
							cout << '\t' << menu_items[i].display() << endl;
			}
			cout << endl;
			break;
		}
	case 3:
		{
			//B.1.c All Menu Items in a Category
			cout << "Not implemented";
			cout << endl;
			break;
		}
	
	default:
		cout << "Invalid request\n";
	}
	
}
void ROMS_Menu::find() const 
{	//Below is some old code from Part I. What changes, if any are needed for Part II?
	//cout << "Find queries \n";
	//B.2.a,b,c merge 
	cout << "Enter find query number:" << endl;
	cout << "1-Total Sales for a Table 2-Total Sales for a Server 3-Total Sales for a Menu Item\n";
	int find_num;
	cin >> find_num;
	switch (find_num) 
	{
	case 1:
		//cout << "Not implemented\n";
		//break;
		{
			//B.2.a calculate total sales for a given table
			//read table id
			//loop thru orders that have that table, pick order items for those orders, calc menu_item price * qty ordered and add to total
			//print total
			int table_id;
			cout << "Enter Table ID: ";
			cin >> table_id;
			//validate category id
			
			double sales_total = 0;
			//total up all sales for this table.
			for (int i = 0; i < (int)orders.size(); ++i)
			{
				//select an order that includes this table
				if(table_id == orders[i].get_table_id())
				{
					//add this order sales to the table sales total
					int order_id = orders[i].get_order_id();
					for (int j = 0; j < (int)order_items.size(); ++j)
						//select an order item for the current order
						if(order_id == order_items[j].get_order_id()) {
							int menu_item_id = order_items[j].get_menu_item_id();
							double item_price = 0.;
							for (int k = 0; k < (int) menu_items.size(); ++k) 
								if(menu_item_id == menu_items[k].get_menu_item_id()) 
								{
									item_price = menu_items[k].get_price();
									break;
								}
							//add the sale of this item to the table total
							sales_total += item_price * order_items[j].get_qty();
						}
				}
			}
			cout << " Table sales = "<< sales_total << endl;
			break;
		}
	case 2: 
		{
		//B.2.b Total Sales for a Server
			
			cout << "Not implemented" << endl;
			break;
		}
	case 3:
		{
			//B.2.c Total Sales for a Menu Item
			cout << "Not Implemented" << endl;
			break;
		}
	default:
		cout << "Invalid request\n";
	}
}
void ROMS_Menu::update()  
{	//This is some old code from Part I. What changes, if any are needed for Part II?
	//B.3.a, b, c merge //cout << "Update queries \n";
	cout << "Enter update query number: " << endl;
	cout << "1-Add New Order Item 2-Add New Menu Item 3-Add New Categories" << endl;
	int query_num;
	cin >> query_num;
	switch (query_num) 
	{
	case 1:
		{
			//B.1 Add new order item to an existing order
			int order_id, menu_item_id, qty;
			string seat_id;
			cout << "Enter Order_id    Menu_item_id    quantity   seat_id\n";
			cin >> order_id >> menu_item_id >> qty >> seat_id;
			if(!cin) throw InvalidData();
			//check that order_id exists
			int n = 0;
			for(n=0; n<(int)orders.size(); ++n)
				if(orders[n].get_order_id() == order_id) break;
			if(!(n < (int)orders.size())||!cin) throw InvalidData();
			//check that menu item id exists
			n = 0;
			for(n=0; n<(int)menu_items.size(); ++n)
				if(menu_items[n].get_menu_item_id() == menu_item_id) break;
			if(!(n < (int)menu_items.size())||!cin) throw InvalidData();
			//check that quantity is positive--maybe should check some reasonable upper bound, too?
			if(qty < 1) 
				throw InvalidData();
			//check that seat is valid
			if(seat_id < "A" || seat_id > "H")
				throw InvalidData();
			
			//add order item
			order_items.push_back(Order_Item(seat_id, order_id, menu_item_id, qty));

			cout << "Number of order items is now " << order_items.size() << endl;
			break;
		}
	case 2: 
		{
			//B.3.b Add new menu item using an existing recipe to an existing category
			cout << "Not Implemented" << endl;
			break;
		}
	case 3:
		{
			//B.3.c Add New Categories Soups, Salads and Sides
			cout << "Not Implemented " << endl;
			break;
		}
	default:
		cout << "Invalid request\n";
	}
}

//open a file and return the expected number of records
int ROMS_Menu::get_file_info(ifstream& ist, string ptompt, string fname)
{	
	//A.1, 2 & 3 merge
	//string fname;
	//cout << prompt;
	//cin >> fname;
	ist.clear();
	ist.open(fname.c_str());
	if (!ist) throw InvalidFile();
	int num;
	ist >> num;
	if (!ist) throw InvalidData();
	return num;
}
void ROMS_Menu::read_file(ifstream& file, int num_rec, Rec_type ftype)
{
	//A.1, 2 & 3 merge
	//Category_ID Cat_name 
	//example category data: 1010	Appetizers	
	int cat_id;
	string cat_name;

	//Menu_item_ID Category_ID RecipeID Menu_item_name Menu_item_price Description #
	//example menu_item data:	2173	1010	3000	Pastel	2	fried flour dumpling filled with vegetables and meat #
	int menu_item_id, /*cat_id,*/ rec_id;
	string item_name;
	double item_price;
	string item_dscrp;

	//Order_ID Server_ID Table_ID Order_date Order_time
	//example order data: 7000	6220	1000	2011	4	4	1	11
	int order_id, server_id, table_id;
	int order_year, order_month, order_day;
	int order_hour, order_minute;

	//Seat_ID Order_ID Menu_item_ID Quantity_ordered
	//example order_item data:	A	7000	2834	1
	string seat_id; 
	/*int order_id, menu_item_id;*/ 
	int ord_qty;

	//Ingredient_ID Recipe_ID Amount_required Units Name 
	//example ingredient data: 6000	3619	5	medium	onionssliced
	int ingred_id; /*rec_id*/ 
	float amt_req;
	string units, name;

	//Recipe_ID Chef_name Instructions # 
		//example recipe data:	3015	Astrid	1. Liquidise the prawn meat till smooth. Mix in the tapioca flour, salt and pepper. Mix well into a stiff dough.
//2. Divide dough into three equal portions. Roll up each portion then place the rolls on a greased plate. Steam for 40 to 45 minutes over high flame.
//3.Leave the rolls to cool, then wrap with a clean tea towel. Chill well in the refrigerator. Use a very sharp knife to slice thinly. Thoroughly dry the cut-out pieces in the sun.
//4. Deep-fry the crackers   #	
	//int rec_id;
	string chef_name;
	string instr;

	//read given file
	int i = 0; 
	while(file && i < num_rec)
	{
		switch(ftype) {	//Rec_type{ Cats=1, Menu_entry, Rec, Ingred, Ord, Ord_item };
			case ROMS_Menu::Rec:
				file >> rec_id >> chef_name;
				instr = get_long_string(file);
				recipes.push_back(Recipe(rec_id, chef_name, Instructions(instr)));
				break;
			case ROMS_Menu::Ingred:
				file >> ingred_id >> rec_id >> amt_req >> units >> name;
				ingredients.push_back(Ingredient(ingred_id, rec_id, amt_req, units, name));
				break;
			case ROMS_Menu::Ord:
				file >> order_id >> server_id >> table_id >> order_year >> order_month >> order_day >> order_hour >> order_minute;
				orders.push_back(Order(order_id, server_id, table_id, Date(order_year, (Date::Month)order_month, order_day), Time(order_hour,order_minute)));
				break;
			case ROMS_Menu::Ord_item:
				file >> seat_id >> order_id >> menu_item_id >> ord_qty;
				order_items.push_back(Order_Item(seat_id, order_id, menu_item_id, ord_qty));
				break;
			case ROMS_Menu::Cats:
				file >> cat_id >> cat_name;
				categories.push_back(Category(cat_id, cat_name));
				break;
			case ROMS_Menu::Menu_entry:
				file >> menu_item_id >> cat_id >> rec_id >> item_name >> item_price;
				item_dscrp = get_long_string(file);
				menu_items.push_back(Menu_Item(menu_item_id, cat_id, rec_id, item_name, item_price, Description(item_dscrp)));
				break;
			default:
				throw InvalidData();
		}
		++i;
	}
	if(i != num_rec || !file) throw InvalidData();
}
string ROMS_Menu::get_long_string(ifstream& file) 
{
	string result, s;
	file >> result;
	if(result == "#") return "";
	char chr;
	file >> noskipws >> chr;
	while (file && !(chr == '#')) {
		stringstream ss;
		ss << result << chr;
		result = ss.str();
		file >> noskipws >> chr;
	}
	file >> skipws;
	return result;
}


//show functions added to support GUI interface

string ROMS_Menu::show_button(Msg_type type)
{
	switch(type) {
	case Tables_button:
		return show_func_w_header(recipes, "Recipes");
	case Orders_button:
		return show_func_w_header(orders, "Orders");
	case Categories_button:
		//return show_func(categories, "Category");
		return show_category();
	case Menu_items_button:
		return show_func_w_header(menu_items, "Menu Items");
		//return show_menu_item(); //HHC Part II B.3
	case Recipes_button:
		//return show_func(order_items, "Order Items");
		return show_order_item(); //HHC Part II B.3
	default:
		throw InvalidType();
	}
}


	/***** ADDED FUNCTIONS *****/

	string ROMS_Menu::show_category(){ //showing menu item names associated with each category
	string r;
	ostringstream oss;
	if(0==categories.size())
		oss << "No Category Data Loaded\n";
	else{
		oss << categories[0].header() << endl;//[THORIQ-B.2]
		for(int i=0; i<categories.size(); ++i)
		{
			oss << categories[i].display();
			oss << getMenuItemsByCatID(categories[i].get_cat_id());
			oss << endl;
		}
	}
	return oss.str();

	}; //HHC Part II B.3

	string ROMS_Menu::getMenuItemsByCatID (int CatID) const{
		string result="";
		for(int i = 0; i<menu_items.size(); ++i){
			if(menu_items[i].get_cat_id()==CatID){
				result+=menu_items[i].get_name()+", ";//add the menu item name to the list
			}
		}
		if(result=="") result = "-";
		return result;
	}; // HHC Part II B.3

	string ROMS_Menu::show_order_item(){ //displaying the order items groups with their order information
		string r;
		ostringstream oss;
		if(0==order_items.size())
			oss << "No Menu Item Data Loaded\n";
		else{
			oss << left << setw(6) << "Seat"
				<< left << setw(8) << "Order"
				<< left << setw(10) << "MenuItem"
				<< left << setw(10) << "Qty"
				<< left << setw(10) << "Order"
				<< left << setw(10) << "Server"
				<< left << setw(10) << "Table"
				<< left << setw(16) << "Order Date"
				<< "Order Time";
			oss << endl;
			for(int i=0; i<order_items.size(); ++i)
			{
				//r+=order_items[i].display();
				oss << order_items[i].display();
				oss << '\t';
				oss << getOrderByOrderID(order_items[i].get_order_id()).display();
				oss << endl;
			}
		}
		return oss.str();

	}; //HHC Part II B.3

	Order ROMS_Menu::getOrderByOrderID (int OrderID) const{
		bool found = false;
		for(int i = 0; i<orders.size()&&!found; ++i){
			if(orders[i].get_order_id()==OrderID){
				found = true;
				return orders[i];//return the associated order
			}
		}
		return (orders[0]);//default
	}; // HHC Part II B.3

/*** WRONG
	string ROMS_Menu::show_menu_item(){
		string r;
		if(0==menu_items.size())
			r = "No Menu Item Data Loaded\n";
		else{
			r = "Menu name | Menu ID | Price | Category\n"
			for(int i=0; i<menu_items.size(); ++i)
			{
				r+=menu_items[i].display();
				r+=" "+getCatnameByCatID(menu_items[i].get_cat_id());
				r+="\n";
			}
		}
		return r;

	}; //HHC Part II B.3

	}; //HHC Part II B.3

	Category ROMS_Menu::getCatByCatID (int CatID) const{
		bool found = false;
		for(int i = 0; i<categories.size()&&!found; ++i){
			if(categories[i].get_cat_id()==CatID){
				found = true;
				return categories[i];//return the nassociated category
			}
		}
		return (new Category(0,"unknown"));
	}; // HHC Part II B.3
	/******************************/
	
	
	//[THORIQ-B.2]
	//Show menu selections
	string ROMS_Menu::show_menu(Msg_type type) {
		switch(type) {
		case Show_order:
			return show_func_w_header(orders, "Orders");
		case Show_recipe:
			return show_func_w_header(recipes, "Recipes");
		case Show_menu:
			return show_func_w_header(menu_items, "Menu Items");
		default:
			throw InvalidType();
		}
	}

	string ROMS_Menu::findSalesByMenuItemID (int MIID){
		double sales=0;
		Menu_Item check = getMenuItemByID(MIID);
		double price = check.get_price();
		if(order_items.size()==0) return "Warning: Order Items Data is Empty";
		for(int i=0; i<order_items.size(); ++i){
			if(order_items[i].get_menu_item_id()==MIID){
				sales += price*order_items[i].get_qty();
			}
		}
		ostringstream oss;
		oss <<"Total Sales of " << check.get_name() << " (ID = " << check.get_menu_item_id() << " ) is $" << sales << endl;
		return oss.str();
	} //HHC Part II C

	Menu_Item ROMS_Menu::getMenuItemByID(int MenuitemID){
	for(int i = 0; i<menu_items.size(); ++i){
		if(menu_items[i].get_menu_item_id()==MenuitemID){
			return menu_items[i];
		}
	}
	Menu_Item dflt = Menu_Item(-1,-1,-1,"",0,Description(""));
	return dflt;
	}; //HHC Part II C

	bool ROMS_Menu::updateMenuItem(int MenuitemID, int catID, int recID, string name, double prc, string desc){
	for(int i = 0; i<menu_items.size(); ++i){
		if(menu_items[i].get_menu_item_id()==MenuitemID){
			menu_items[i].update(MenuitemID,catID,recID,name,prc,Description(desc));
			return true; //return true if MenuitemID is exist, it means edit the data
		}
	}
	//Menu Item ID doesn't exist, create new item
	menu_items.push_back(Menu_Item(MenuitemID,catID,recID,name,prc,Description(desc)));
	return false; //return false if MenuitemID hasn't existed, it means add new menu item
	}; //HHC Part II C
	
	/***********************[THORIQ-C]**************************/
	//count total sales for the specified category
	double ROMS_Menu::get_category_sales(int id)
	{
		double sum = 0;
		for(int i = 0; i < order_items.size(); ++i)
		{
			for(int j = 0; j < menu_items.size(); ++j)
			{
				if(order_items.at(i).get_menu_item_id() == menu_items.at(j).get_menu_item_id())
				{
					if(menu_items.at(j).get_cat_id() == id)
					{
						sum += order_items.at(i).get_qty() * menu_items.at(j).get_price();
					}
				}
			}
		}
		return sum;
	}
	
	//return true if category with the specified ID is found within categories vector
	bool ROMS_Menu::is_category_available(int id)
	{
		for(int i = 0; i < categories.size(); ++i)
		{
			if(categories.at(i).get_cat_id() == id)
			{
				return true;
			}
		}
		return false;
	}

	//add a new recipe to the recipes vector if allowed
	string ROMS_Menu::add_recipe(int id, string chef, string instructions)
	{
		stringstream ss;
		if(id==-999999 || chef=="" || instructions=="")
		{
			return "Please fill all of the input forms";
		}
		for (int i = 0; i < recipes.size(); i++)
		{
			if (recipes.at(i).get_rec_id() == id) //recipe with this id already exists
			{
				stringstream ss;
				ss << "Recipe with ID #" << id << " already exists";
				return ss.str();
			}
		}
		Recipe new_recipe(id, chef, instructions);
		recipes.push_back(new_recipe);
		return "New recipe has been added";
	}
	/***************************************************************/
	
	void ROMS_Menu::updateOrderItem(string seatid, int orderid, int menuitemid, int qnty) //TTL PartC
	{
		order_items.push_back(Order_Item(seatid,orderid,menuitemid,qnty));

	}; //TTL PartC
	
	int ROMS_Menu::getMonthbyOrderID(int OrderID){
		for(int i = 0; i<orders.size(); ++i){
			if(orders[i].get_order_id()== OrderID)
				return orders[i].getMonth();
		}
		return 0;
	}//HHC Part II D.1

	map<int,double> ROMS_Menu::getPricelist(){
		map<int,double> prices; //mapping from Menu Item ID to it's price
		for(int i = 0; i<menu_items.size(); ++i)
			prices[menu_items[i].get_menu_item_id()] = menu_items[i].get_price();
		return prices;
	}//HHC Part II D.1

	map<int,double> ROMS_Menu::get_sales_per_month(){
		map<int,double> sales; //1=jan, 12=dec
		int OrderID, MIID;
		map<int,double> prices = getPricelist();
		for(int i=0; i<order_items.size(); ++i){
			//add sales to associated month
			sales[getMonthbyOrderID(order_items[i].get_order_id())] += prices[order_items[i].get_menu_item_id()]*order_items[i].get_qty();
		}
		return sales;
	}; //HHC Part II D.1

	/***********************[THORIQ-D]**************************/
	//return the total sales of the specified category per month
	vector<double> ROMS_Menu::get_category_sales_per_month(int cat_id) {
		vector<double> sales_vector;
		//category's total sales for each month are stored here
		double jan = 0, feb = 0, mar = 0, apr = 0, may = 0, jun = 0, jul = 0, aug = 0, sep = 0, oct = 0, nov = 0, dec = 0;

		for(int k = 0; k < orders.size(); ++k) {
			for(int i = 0; i < order_items.size(); ++i) {
				if(order_items.at(i).get_order_id() == orders.at(k).get_order_id()) {
					for(int j = 0; j < menu_items.size(); ++j) {
						if(order_items.at(i).get_menu_item_id() == menu_items.at(j).get_menu_item_id()) {
							if(menu_items.at(j).get_cat_id() == cat_id) {
								switch(orders.at(k).getMonth()) {
									case Date::jan:
										jan += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::feb:
										feb += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::mar:
										mar += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::apr:
										apr += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::may:
										may += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::jun:
										jun += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::jul:
										jul += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::aug:
										aug += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::sep:
										sep += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::oct:
										oct += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::nov:
										nov += order_items.at(i).get_qty() * menu_items.at(j).get_price();
										break;
									case Date::dec:
										dec += order_items.at(i).get_qty() * menu_items.at(j).get_price();
								}
							}
						}
					}
				}
			}
		}
		sales_vector.push_back(jan);
		sales_vector.push_back(feb);
		sales_vector.push_back(mar);
		sales_vector.push_back(apr);
		sales_vector.push_back(may);
		sales_vector.push_back(jun);
		sales_vector.push_back(jul);
		sales_vector.push_back(aug);
		sales_vector.push_back(sep);
		sales_vector.push_back(oct);
		sales_vector.push_back(nov);
		sales_vector.push_back(dec);
		return sales_vector;		
	}

	//return a map containing the percentage of each category sales per month
	map<int,map<int,double> > ROMS_Menu::get_category_percentage() {
		map<int,map<int,double> > cat_percentage; //month as keys, category IDs as keys of the second map, percentage amounts as the values
		map<int,double> sales_jan; //sales map for january
		map<int,double> sales_feb;
		map<int,double> sales_mar;
		map<int,double> sales_apr;
		map<int,double> sales_may;
		map<int,double> sales_jun;
		map<int,double> sales_jul;
		map<int,double> sales_aug;
		map<int,double> sales_sep;
		map<int,double> sales_oct;
		map<int,double> sales_nov;
		map<int,double> sales_dec;
		map<int,double> sales_per_month = get_sales_per_month(); //get the total sales per month using Hendra's function
		
		for(int i = 0; i < categories.size(); ++i) {
			vector<double> cat_sales = get_category_sales_per_month(categories.at(i).get_cat_id());
			sales_jan.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[1] != 0? (cat_sales.at(0)/sales_per_month[1]): 0)));
			sales_feb.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[2] != 0? (cat_sales.at(1)/sales_per_month[2]): 0)));
			sales_mar.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[3] != 0? (cat_sales.at(2)/sales_per_month[3]): 0)));
			sales_apr.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[4] != 0? (cat_sales.at(3)/sales_per_month[4]): 0)));
			sales_may.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[5] != 0? (cat_sales.at(4)/sales_per_month[5]): 0)));
			sales_jun.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[6] != 0? (cat_sales.at(5)/sales_per_month[6]): 0)));
			sales_jul.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[7] != 0? (cat_sales.at(6)/sales_per_month[7]): 0)));
			sales_aug.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[8] != 0? (cat_sales.at(7)/sales_per_month[8]): 0)));
			sales_sep.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[9] != 0? (cat_sales.at(8)/sales_per_month[9]): 0)));
			sales_oct.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[10] != 0? (cat_sales.at(9)/sales_per_month[10]): 0)));
			sales_nov.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[11] != 0? (cat_sales.at(10)/sales_per_month[11]): 0)));
			sales_dec.insert(make_pair(categories.at(i).get_cat_id(), (sales_per_month[12] != 0? (cat_sales.at(11)/sales_per_month[12]): 0)));
		}

		//insert category sales percentages for each month
		cat_percentage.insert(make_pair(1, sales_jan));
		cat_percentage.insert(make_pair(2, sales_feb));
		cat_percentage.insert(make_pair(3, sales_mar));
		cat_percentage.insert(make_pair(4, sales_apr));
		cat_percentage.insert(make_pair(5, sales_may));
		cat_percentage.insert(make_pair(6, sales_jun));
		cat_percentage.insert(make_pair(7, sales_jul));
		cat_percentage.insert(make_pair(8, sales_aug));
		cat_percentage.insert(make_pair(9, sales_sep));
		cat_percentage.insert(make_pair(10, sales_oct));
		cat_percentage.insert(make_pair(11, sales_nov));
		cat_percentage.insert(make_pair(12, sales_dec));

		//for debugging purpose
		map<int,map<int,double> >::iterator iter;
		for(iter=cat_percentage.begin(); iter!=cat_percentage.end(); iter++) {
			cout << "month: " << iter->first << endl;
			map<int,double>::iterator in_iter;
			for(in_iter=iter->second.begin(); in_iter!=iter->second.end(); in_iter++) {
				cout << "\t#" << in_iter->first << ": " << in_iter->second << endl;
			}
		}
		return cat_percentage;
	}



